#!/usr/bin/env python
"""

Referencing current branch in github README.md [1]
This pre-commit hook [2] updates the README.md file's
Travis badge with the current branch. Based on [4].

[1] http://stackoverflow.com/questions/18673694/referencing-current-branch-in-github-readme-md
[2] http://www.git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
[3] https://docs.travis-ci.com/user/status-images/
[4] https://gist.github.com/dandye/dfe0870a6a1151c89ed9

Copy this file to .git/hooks/

"""

import os
import re
import string
import sys
import argparse
from subprocess import call, check_output

try:
    from urllib.parse import urlparse
except ImportError:
    from urlparse import urlparse

from fileinput import FileInput

# TODO: drop after platform.io supports python 3
# https://github.com/python/cpython/commit/6cb7b659#diff-78790b53ff259619377058acd4f74672
if sys.version_info[0] < 3:
    class FileInputCtx(FileInput):
        def __enter__(self):
            return self

        def __exit__(self, type, value, traceback):
            self.close()


    FileInput = FileInputCtx


class CustomFormatter(string.Formatter):
    def format_field(self, value, spec):
        if spec == "escape_hyphen":
            return value.replace("-", "--")
        else:
            return super(CustomFormatter, self).format_field(value, spec)


def run(cmd, cwd=None):
    out = check_output(cmd, cwd=cwd)
    out = out.decode("latin1").strip()

    return out


def parse_h_string(define, r_quotes=re.compile("\"(.*)\"")):
    string = r_quotes.search(define).group(1)
    return string


def git_parse_remote(cwd=None, remote="origin"):
    remote_url = run([
        "git", "config", "--local",
        "--get", "remote.{}.url".format(remote)], cwd)

    if remote_url.startswith("git"):
        _, _, repo = remote_url.partition(":")
        path = repo.replace(".git", "")
    elif remote_url.startswith("https"):
        parsed = urlparse(remote_url)
        path = parsed.path[1:]
    return path.split("/")


def git_branch(cwd=None):
    return run(["git", "rev-parse", "--abbrev-ref", "HEAD"], cwd)


def espurna_get_version(base, version_h="code/espurna/config/version.h"):
    version = "unknown"

    path = os.path.join(base, version_h)
    with open(path, "r") as version_f:
        for line in version_f:
            if line.startswith("#define") and "APP_VERSION" in line:
                version = parse_h_string(line)
                break

    return version


TEMPLATES = {
    "![travis]": "[![travis](https://travis-ci.org/{USER}/{REPO}.svg?branch={BRANCH})]"
                 "(https://travis-ci.org/{USER}/{REPO})\n",
    "![version]": "[![version](https://img.shields.io/badge/version-{VERSION:escape_hyphen}-brightgreen.svg)]"
                  "(CHANGELOG.md)\n",
    "![branch]": "[![branch](https://img.shields.io/badge/branch-{BRANCH:escape_hyphen}-orange.svg)]"
                 "(https://github.com/{USER}/{REPO}/tree/{BRANCH}/)\n",
}

README = "README.md"

if __name__ == "__main__":

    base = os.getcwd()
    user, repo = git_parse_remote()

    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument("-b", "--branch", help="git branch name", default=git_branch())
    parser.add_argument("-u", "--user", help="git user name", default=user)
    parser.add_argument("-r", "--repo", help="git repo name", default=repo)
    parser.add_argument("-v", "--version", help="ESPurna version", default=espurna_get_version(base))
    args = parser.parse_args()

    fmt = {
        "USER": args.user,
        "REPO": args.repo,
        "BRANCH": args.branch,
        "VERSION": args.version
    }

    formatter = CustomFormatter()
    templates = [
        (k, formatter.format(tmpl, **fmt))
        for k, tmpl in TEMPLATES.items()
    ]


    def fmt_line(line):
        for match, tmpl in templates:
            if match in line:
                return tmpl

        return line


    path = os.path.join(base, README)

    with FileInput(path, inplace=True) as readme:
        for line in readme:
            sys.stdout.write(fmt_line(line))

    if call(["git", "add", README]):
        sys.exit(1)

    sys.exit(0)
